﻿using K9Nano.Dependency;

namespace K9Nano.Domain.Caching;

public class DefaultEntityCachedTypeFinder : IEntityCachedTypeFinder, ISingletonDependency
{
    private readonly Dictionary<Type, Type[]> _cache;

    public DefaultEntityCachedTypeFinder(IIocHelper iocHelper)
    {
        _cache = [];

        var baseName = typeof(IEntityCache<,>).FullName;

        _cache = iocHelper.GetRegisteredTypes<IEntityCache>()
            .Select(cacheType =>
            {
                var baseType = cacheType.GetInterfaces()
                    .FirstOrDefault(x => x.FullName?.StartsWith(baseName!) == true)
                    ?? throw new Exception($"{cacheType} must implement IEntityCache<,>");
                return new
                {
                    entityType = baseType.GenericTypeArguments[0],
                    cacheItemType = baseType.GenericTypeArguments[1]
                };
            })
            .GroupBy(x => x.entityType)
            .ToDictionary(x => x.Key, x => x.Select(a => a.cacheItemType).ToArray());
    }

    public IReadOnlyList<Type> Find(Type entityType)
    {
        if (_cache.TryGetValue(entityType, out Type[]? value))
        {
            return value;
        }
        return [];
    }
}